///////////////////////////////////////////////////////////////////////////////
//
// Copyright
//
///////////////////////////////////////////////////////////////////////////////

package ru.goodcore.resource
{

import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.TimerEvent;
import flash.system.ApplicationDomain;
import flash.system.System;
import flash.utils.Timer;

import ru.goodcore.resource.errors.ResourceBundleError;

//-------------------------------------
//  Events
//-------------------------------------

/**
 *  Dispatched when resource vault is ready 
 *
 *  @eventType flash.events.Event
 */
[Event(name="complete", type="flash.events.Event")]


/**
 * 
 * @author					Dimarik
 * @version					1.0
 * @playerversion			Flash 9
 * @langversion				3.0
 *
 * @keyword					
 */
public class ResourceVault extends EventDispatcher
{

	include "../../../includes/core/Version.as";

	//-------------------------------------------------------------------------
	//
	//  Public class's constants
	//
	//-------------------------------------------------------------------------

	//-------------------------------------------------------------------------
	//
	//  Class properties
	//
	//-------------------------------------------------------------------------

	//-------------------------------------------------------------------------
	//
	//  Class variables
	//
	//-------------------------------------------------------------------------

	//-------------------------------------------------------------------------
	//
	//  Class methods
	//
	//-------------------------------------------------------------------------

	//-------------------------------------------------------------------------
	//
	//  Private class variables
	//
	//-------------------------------------------------------------------------

	//-------------------------------------------------------------------------
	//
	//  Constructor
	//
	//-------------------------------------------------------------------------

	/**
	 * Constructor
	 */
	public function ResourceVault() {
		super();
	}

	//-------------------------------------------------------------------------
	//
	//  Properties
	//
	//-------------------------------------------------------------------------

	//-------------------------------------
	//  appDomain
	//-------------------------------------
	/**
	 * @private
	 */
	private var _appDomain:	ApplicationDomain;

	public function get appDomain():ApplicationDomain {
		return this._appDomain;
	}

	public function set appDomain(value:ApplicationDomain):void {
		if (this._appDomain == value) return;
		this._appDomain = value;
	}

	//-------------------------------------
	//  priority
	//-------------------------------------
	/**
	 * @private
	 */
	private var _priority:	uint;

	public function get priority():uint {
		return this._priority;
	}

	public function set priority(value:uint):void {
		if (this._priority == value) return;
		this._priority = value;
	}

	//-------------------------------------
	//  farewellTimer
	//-------------------------------------
	/**
	 * @private
	 */
	private var _farewellTimeOut:	Number = 5 * 60 * 1e3; // 5 min default

	private var _farewellTimer:		Timer;

	public function get farewellTimer():Timer {
		return this._farewellTimer;
	}

	//-------------------------------------
	//  ready
	//-------------------------------------
	/**
	 * @private
	 */
	private var _ready:	Boolean;

	public function get ready():Boolean {
		return this._ready;
	}

	//-------------------------------------
	//  dispatcher
	//-------------------------------------
	/**
	 * @private
	 */
	private var _dispatcher:	IEventDispatcher;

	public function get dispatcher():IEventDispatcher {
		return this._dispatcher;
	}

	public function set dispatcher(value:IEventDispatcher):void {
		if (this._dispatcher == value) return;

		if (this._dispatcher) {
			this._dispatcher.removeEventListener(Event.COMPLETE, this.handler_ready);
		}

		this._dispatcher = value;

		if (this._dispatcher) {
			this._dispatcher.addEventListener(Event.COMPLETE, this.handler_ready);
		}

	}

	//-------------------------------------------------------------------------
	//
	//  Private variables
	//
	//-------------------------------------------------------------------------

	//-------------------------------------------------------------------------
	//
	//  Public methods
	//
	//-------------------------------------------------------------------------

	public function getResource(resourceSignature:String):* {
		if ( !this._ready ) {
			throw new ResourceBundleError(ResourceBundleError.MISSING_BUNDLE, [resourceSignature]);
			return;
		}

		if (this._appDomain && this._appDomain.hasDefinition(resourceSignature)) {
			
			return this._appDomain.getDefinition(resourceSignature);
		}

		return null;
	}

	//-------------------------------------------------------------------------
	//
	//  Protected methods
	//
	//-------------------------------------------------------------------------

	//-------------------------------------------------------------------------
	//
	//  Private methods
	//
	//-------------------------------------------------------------------------

	//-------------------------------------------------------------------------
	//
	//  Event handlers
	//
	//-------------------------------------------------------------------------

	/**
	 * @private
	 * @param event
	 */
	private function handler_ready(event:Event):void {
		this._dispatcher.removeEventListener(Event.COMPLETE, this.handler_ready);
		this._dispatcher = null;
		this._farewellTimer = new Timer(this._farewellTimeOut, 1);
		this._farewellTimer.addEventListener(TimerEvent.TIMER_COMPLETE, this.handler_timerComplete);
		this._farewellTimer.start();
		this._ready = true;
		super.dispatchEvent( new Event(Event.COMPLETE) );
	}

	/**
	 * @private
	 * @param event
	 */
	private function handler_timerComplete(event:TimerEvent):void {
		IEventDispatcher(event.target).removeEventListener(event.type, arguments.callee);
		this._farewellTimer.stop();
		this._farewellTimer = null;
		this._appDomain = null;
		this._ready = false;
		//trace('release resource');
		System.gc();
	}


}
}